# coding=utf-8
# !/usr/bin/env python
import Queue
import json
import logging

from flask_socketio import Namespace, emit

from ..common import pipeline_manager
from ..common.pipelines import PipelineStatusListner, PipelineEvent
from ..common.utils import ComplexEncoder
from ..common.autoTest import TestMessage

thread = None
NAMESPACE = '/notify'
EVENT = 'stat'
send_queue = Queue.Queue()
import traceback

log = logging.getLogger(__name__)


def send_message(data):
    try:
        send_queue.put(packling(data), block = True, timeout = 10)
    except:
        log.error(u"Notifer消息入队失败!")
        log.error(traceback.format_exc())


def packling(event):
    if isinstance(event, PipelineEvent):
        return event.to_dict()
    elif isinstance(event, TestMessage):
        return event


class NotiferPipelineStatusListner(PipelineStatusListner):
    def on_event(self, event):
        send_message(event)


def background_thread(socketio):
    pipeline_status_listner = NotiferPipelineStatusListner()
    pipeline_manager.subscribe(pipeline_status_listner)
    while True:
        socketio.sleep(0.1)
        data = None
        try:
            data = send_queue.get(block = False)
            if isinstance(data, TestMessage):
                data = data.to_str()
            else:
                data = json.dumps(data, encoding = "UTF-8", ensure_ascii = False, cls = ComplexEncoder)
            log.info("send data:" + data)
            socketio.emit(EVENT,
                          {'data': data},
                          namespace = NAMESPACE)
        except Queue.Empty:
            continue
        except:
            log.warn(u"Notifer发送消息错误.")
            log.error(traceback.format_exc())


class NotifierNamespace(Namespace):
    def __init__(self, ):
        super(NotifierNamespace, self).__init__(namespace = NAMESPACE)

    def on_my_ping(self):
        emit('my_pong')

    def on_connect(self):
        global thread
        if thread is None:
            thread = self.socketio.start_background_task(background_thread, self.socketio)
        emit(EVENT, {'data': 'Connected'})
